#![no_std]
#![no_main]
#![warn(missing_docs)]
#![deny(warnings)]
#![feature(custom_test_frameworks)]
#![feature(alloc_error_handler)]
#![test_runner(crate::test::test_runner)]
#![reexport_test_harness_main = "test_main"]
#![feature(abi_x86_interrupt)]

//! 包括内核主要模块和初始化部分，使集成测试程序和主程序可以复用大部分代码

#[macro_use]
// 驱动管理
pub mod driver;

// 测试管理
pub mod test;

/// 各类初始化函数
pub fn init<'a>(boot_info: &'a mut bootloader_api::BootInfo) {
    // 初始化串口
    driver::serial::init();

    // 初始化FrameBuffer
    driver::fb::init(boot_info.framebuffer.as_mut().unwrap());
}

/// 进入休眠状态
pub fn hlt_loop() -> ! {
    loop {
        x86_64::instructions::hlt();
    }
}

#[panic_handler]
// Rust语言要求的panic处理函数，通常由标准库提供，我们需要自己实现
fn panic(info: &core::panic::PanicInfo) -> ! {
    // 格式化打印PanicInfo，通过串口输出至终端
    serial_println!("{}", info);
    test::exit_qemu(test::QemuExitCode::Failed);
    hlt_loop();
}

#[cfg(test)]
// 测试lib.rs需要单独定义入口
// 使用bootloader_api库提供的宏声明内核入口
bootloader_api::entry_point!(kernel_main);

#[cfg(test)]
/// 内核入口函数，参数为bootloader收集的硬件信息
fn kernel_main(boot_info: &'static mut bootloader_api::BootInfo) -> ! {
    init(boot_info);
    test_main();
    hlt_loop();
}

#[test_case]
/// 测试用例示例
fn test_dummy() {
    assert_eq!(1, 1);
}
